import { AuthApi } from '@/entities/auth/api';
import { FileWithPreview } from '@/shared/interfaces';
import { removeData, storage, storeData } from '@/shared/lib';
import { createAction, createAsyncThunk } from '@reduxjs/toolkit';

const AuthApiService = new AuthApi();

// Войти через соц сеть
export const signInSocial = createAsyncThunk('auth/sign-in-social', async (code: string, thunkApi) => {
  try {
    const res = await AuthApiService.signInSocial(code);

    const { accessToken, refreshToken } = res;
    if (accessToken && refreshToken) {
      await storeData('accessToken', accessToken);
      await storeData('refreshToken', refreshToken);
      return res;
    }
    throw new Error('incorrect code');
  } catch (err: any) {
    console.info('ERROR: ', err);
    return thunkApi.rejectWithValue(err.message);
  }
});

// Подтвердить изменение типа авторизации на авторизацию по почте и паролю
export const changeAuthType = createAsyncThunk(
  'auth/change-auth-type',
  async (data: { password: string }, thunkApi) => {
    try {
      const res = await AuthApiService.changeAuthType(data);
      if (res.statusCode) throw new Error(res.message);
      await removeData('isAuthByPhone');
      return res;
    } catch (err: any) {
      console.error('Ошибка при подтверждении изменения типа авторизации:', err);
      return thunkApi.rejectWithValue(err.message);
    }
  },
);

// Получаем новую пару токенов
export const refreshTokenPair = createAsyncThunk('auth/refresh-token-pair', async (_, thunkApi) => {
  try {
    // const state = thunkApi.getState() as RootState;

    // // Получаем статус текущего интернет соединения
    // const { connection } = state.app;

    // Если подключение отсутствует - не пытаемся обновить токены
    const refreshToken = await storage.getRefreshToken();
    console.info('REFRESH_TOKEN: ', refreshToken);
    if (!refreshToken) throw new Error('No refresh token');

    // Обновляем пару токенов
    const res = await AuthApiService.refreshToken(refreshToken);

    if (res.statusCode) throw new Error('incorrect refresh token');

    if (res.accessToken && res.refreshToken) {
      await storage.setAccessToken(res.accessToken);
      await storage.setRefreshToken(res.refreshToken);
      return res;
    }
    throw new Error('no tokens');
  } catch (err: any) {
    console.info('Ошибка обновления пары токенов:', err.message);
    await storage.clearTokens();
    return thunkApi.rejectWithValue(err.message);
  }
});

export const setFeedbackFiles = createAction('auth/set-feedback-files', (files: FileWithPreview[]) => ({
  payload: files,
}));

export const setCheckAuth = createAction(
  'auth/set-check-auth',
  ({ userId, email, expiresIn }: { userId: number; email?: string; expiresIn: number }) => ({
    payload: { userId, email, expiresIn },
  }),
);

export const setInAuth = createAction('auth/set-inauth');

export const clearFeedbackFiles = createAction('auth/clear-feedback-files');

export const clearEmailAuthError = createAction('auth/clear-email-auth-error');

// Отправить сообщение обратной связи
export const sendFeedbackMessage = createAsyncThunk(
  'auth/send-feedback-message',
  async ({ data, noAuth }: { data: FormData; noAuth: boolean }, thunkApi) => {
    try {
      const res = await AuthApiService.sendFeedbackMessage(data, noAuth);
      if (res.statusCode) throw new Error(res.message);
      return res;
    } catch (err: any) {
      console.info('Ошибка отправки сообщения обратной связи: ', err.message);
      return thunkApi.rejectWithValue({ error: err.message });
    }
  },
);

// ЛОГАУТ
export const signOut = createAsyncThunk('auth/sign-out', async (_, thunkApi) => {
  try {
    await AuthApiService.signOut();
    localStorage.removeItem('accessToken');
    localStorage.removeItem('refreshToken');
    localStorage.removeItem('authEmail');

    return true;
  } catch (err: any) {
    console.info('Ошибка при разлогине: ', err.message);
    return thunkApi.rejectWithValue(err.message);
  }
});

// Проверить, зарегистрирован ли на почту профиль
export const checkEmailExist = createAsyncThunk('auth/check-email-exist', async (email: string, thunkApi) => {
  try {
    const res = await AuthApiService.checkEmailExist(email);
    if (res.statusCode) throw new Error(res.message);
    return res;
  } catch (err: any) {
    console.info('Ошибка проверки, что почта зарегистрирована');
    return thunkApi.rejectWithValue(err.message);
  }
});

// Сброс статуса проверки регистрации по почте
export const clearEmailStatus = createAction('auth/clear-email-status');

// Установить почту, с которой будет проводиться авторизация или регистрация
export const setCurrentEmail = createAction('auth/set-current-email', (email: string) => ({
  payload: email,
}));

// Установить почту, с которой проводилась текущая авторизация
export const setAuthEmail = createAsyncThunk('auth/set-auth-email', async (email: string) => {
  await storeData('authEmail', email);
  return email;
});

// Регистрация по почте
export const registrationByEmail = createAsyncThunk(
  'auth/registration-via-email',
  async (data: { email: string; password: string }, thunkApi) => {
    try {
      const res = await AuthApiService.registrationByEmail(data);
      if (res.statusCode) throw new Error(res.message);
      const { accessToken, refreshToken } = res;

      if (accessToken && refreshToken) {
        await storage.setAccessToken(accessToken);
        await storage.setRefreshToken(refreshToken);
        return res;
      }
      throw new Error('no accessToken or refreshToken');
    } catch (err: any) {
      console.error('Ошибка при регистрации по почте:', err.message);
      return thunkApi.rejectWithValue(err.message);
    }
  },
);

// Авторизация по почте
export const authByEmail = createAsyncThunk(
  'auth/auth-by-email',
  async (data: { email: string; password: string }, thunkApi) => {
    try {
      const res = await AuthApiService.authByEmail(data);
      if (res.statusCode) throw new Error(res.message);
      const { accessToken, refreshToken } = res;

      if (accessToken && refreshToken) {
        storage.setAccessToken(accessToken);
        storage.setRefreshToken(refreshToken);
        return res;
      }
      throw new Error('no accessToken or refreshToken');
    } catch (err: any) {
      console.error('Ошибка при авторизации по почте:', err.message);
      return thunkApi.rejectWithValue(err.message);
    }
  },
);

// Cбросить статус ошибки/успеха авторизации по почте
export const clearAuthByEmailStatus = createAction('auth/clear-auth-by-email-status');

// email общий
export const setEmailAuthProcess = createAction<string>('auth/set-email-auth-process');

// Получить новый пароль на почту
export const restorePassword = createAsyncThunk('auth/restore-password', async (data: { email: string }, thunkApi) => {
  try {
    const res = await AuthApiService.restorePassword(data);
    if (res.statusCode) throw new Error(res.message);
    return res;
  } catch (err: any) {
    console.error('Ошибка при запросе нового пароля на почту:', err);
    return thunkApi.rejectWithValue(err.message);
  }
});

// Установить статус редиректа на Feedback
export const toggleGoToFeedback = createAction('auth/go-to-feedback');

// Сбросить ошибку при авторизации
export const clearError = createAction('auth/clear-error');

// Запросить генерацию нового пароля после авторизации по номеру телефона
// export const generatePassword = createAsyncThunk(
//   'auth/generate-password',
//   async (data: { email: string }, thunkApi) => {
//     try {
//       const res = await AuthApi.generatePassword(data);
//       if (res.statusCode) throw new Error(res.message);
//       return res;
//     } catch (err: any) {
//       console.error('Ошибка при запросе генерации нового пароля:', err);
//       return thunkApi.rejectWithValue(err.message);
//     }
//   },
// );

// Подтвердить изменение типа авторизации на авторизацию по почте и паролю
// export const changeAuthType = createAsyncThunk(
//   'auth/change-auth-type',
//   async (data: { password: string }, thunkApi) => {
//     try {
//       const res = await AuthApi.changeAuthType(data);
//       if (res.statusCode) throw new Error(res.message);
//       await removeData('isAuthByPhone');
//       return res;
//     } catch (err: any) {
//       console.error('Ошибка при подтверждении изменения типа авторизации:', err);
//       return thunkApi.rejectWithValue(err.message);
//     }
//   },
// );

// Сбросить статус изменения типа авторизации
export const clearAuthType = createAction('auth/clear-auth-type');

// Сбросить статус сравнения введенного пароля с актуальным паролем
export const clearPasswordCorrectStatus = createAction('auth/clear-password-correct-status');

// Изменить пароль
// export const changePassword = createAsyncThunk(
//   'auth/change-password',
//   async (data: { oldPassword: string; newPassword: string }, thunkApi) => {
//     try {
//       const res = await AuthApi.changePassword(data);
//       if (res.statusCode) throw new Error(res.message);
//       return res;
//     } catch (err: any) {
//       console.error('Ошибка при изменении пароля:', err);
//       return thunkApi.rejectWithValue(err.message);
//     }
//   },
// );

// Получить тип авторизации
export const getAuthType = createAsyncThunk('auth/get-auth-type', async (_, thunkApi) => {
  try {
    const res = await AuthApiService.getAuthType();
    if (res.statusCode) throw new Error(res.message);
    return res;
  } catch (err: any) {
    console.info('Ошибка при получении типа авторизации:', err);
    return thunkApi.rejectWithValue(err.message);
  }
});

// Проверить, совпадает ли введенный пароль с актуальным паролем
export const checkPassword = createAsyncThunk('auth/change-password', async (data: { password: string }, thunkApi) => {
  try {
    const res = await AuthApiService.checkPassword(data);
    if (res.statusCode) throw new Error(res.message);
    return res;
  } catch (err: any) {
    console.info('Пароли не совпадают:', err);
    return thunkApi.rejectWithValue(err.message);
  }
});
